package mx.vlabs.soapdroid.wsdl2java.artifactbuilder;

import java.util.List;

import javax.xml.namespace.QName;

import mx.vlabs.soapdroid.wsdl2java.Artifact;
import mx.vlabs.soapdroid.wsdl2java.ElementAttributes;

import org.ow2.easywsdl.schema.api.ComplexType;

import static mx.vlabs.soapdroid.utils.Utils.*;

public class DTOArtifactBuilder extends ArtifactBuilder {
	
	private ComplexType complexType;


	public DTOArtifactBuilder(ComplexType complexType,String packageName) {
		super(packageName);
		this.complexType = complexType;
	}

	@Override
	public String build() {
		// TODO Auto-generated method stub
		String complexTypeNamespace = complexType.getQName().getNamespaceURI();
		String complexTypeName      = complexType.getQName().getLocalPart();
		String complexTypeClassName = capitalizeFirstLetter(complexTypeName);
		
		getArtifact().setName(complexTypeClassName);
		
		List<ElementAttributes> attrsList = ElementAttributes.explode(complexType);
		
		getArtifact().setName(complexTypeClassName);
		getArtifact().setParam("dtoClassName", complexTypeClassName);
		getArtifact().setParam("dtoName", complexTypeName);
		getArtifact().setParam("dtoNamespace", complexTypeNamespace);
		
		boolean firstRun = true;
		
		StringBuilder propOrderStr 		= new StringBuilder();
		StringBuilder fieldDeclarations = new StringBuilder();
		StringBuilder getters		    = new StringBuilder();
		StringBuilder setters	 		= new StringBuilder();
		
		for(ElementAttributes attrs : attrsList){

			propOrderStr.append(buildPropOrderFields(attrs,firstRun));
			fieldDeclarations.append(buildFieldDeclarations(attrs));
			getters.append(buildGetters(attrs));
			setters.append(buildSetters(attrs));
			
			if(firstRun) firstRun = false;
		}
		
		getArtifact().setParam("propOrderFields", propOrderStr.toString());
		getArtifact().setParam("dtoFields", fieldDeclarations.toString());
		getArtifact().setParam("dtoGetters", getters.toString());
		getArtifact().setParam("dtoSetters", setters.toString());
		
		return getArtifact().getContent();
	}
	
	private String buildPropOrderFields(ElementAttributes attrs,boolean firstRun){
		
		String prefix = firstRun ? "\t\"" : ",\n\t\"";
		StringBuilder sb = new StringBuilder(prefix);
		sb.append(((QName)attrs.get("name")).getLocalPart());
		sb.append("\"");
		return sb.toString();
	}
	
	private String buildFieldDeclarations(ElementAttributes attrs){
		
		Artifact art = getArtifactLoader().load("dto.field",getArtifactType());
		
		art.setParam("elementName",((QName) attrs.get("name")).getLocalPart());
		art.setParam("elementNamespace",((QName) attrs.get("name")).getNamespaceURI());
		art.setParam("fieldType", attrs.get("javaType").toString());
		art.setParam("fieldName", attrs.get("javaName").toString());
		
		return art.getContent();

	}
	
	private String buildGetters(ElementAttributes attrs){
		Artifact art = getArtifactLoader().load("dto.getter",getArtifactType());

		art.setParam("isOrGet", attrs.get("javaType").toString().equals("Boolean") ? "is" : "get");
		art.setParam("fieldType",attrs.get("javaType").toString());
		art.setParam("fieldMethodName", capitalizeFirstLetter(((QName) attrs.get("name")).getLocalPart()));
		art.setParam("fieldName", attrs.get("javaName").toString());
		
		String listLogic = "";
		
		if((Boolean) attrs.get("list")){
			Artifact artListLogic = getArtifactLoader().load("dto.getter.listLogic", getArtifactType());
			
			artListLogic.setParam("fieldName", attrs.get("javaName").toString());
			artListLogic.setParam("fieldType", attrs.get("javaElementType").toString());
			
			listLogic = artListLogic.getContent();
		}
		
		art.setParam("listLogic", listLogic);
		
		return art.getContent();
	}
	
	private String buildSetters(ElementAttributes attrs){
		
		String fieldMethodModifier = "public";
		
		if((Boolean) attrs.get("list"))
			fieldMethodModifier = "protected";
		
		Artifact art = getArtifactLoader().load("dto.setter",getArtifactType());
		
		art.setParam("fieldMethodModifier", fieldMethodModifier);
		art.setParam("fieldMethodName", capitalizeFirstLetter(((QName) attrs.get("name")).getLocalPart()));
		art.setParam("fieldType", attrs.get("javaType").toString());
		art.setParam("fieldName", attrs.get("javaName").toString());
		
		return art.getContent();
	}

	@Override
	public String getArtifactType() {
		// TODO Auto-generated method stub
		return "dto";
	}

}
